package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkFormPoJo;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.field.SubFormPoJo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.script.pojo.dto.ProductDTO;
import com.xbongbong.saas.base.EnumBase;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.CostAdjustEnum;
import com.xbongbong.saas.enums.product.CostAdjustProductEnum;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.script.tempenum.TempContractOutstockEnum;
import com.xbongbong.saas.script.tempenum.TempCostAdjustEnum;
import com.xbongbong.saas.script.tempenum.product.TempCostAdjustProductEnum;
import com.xbongbong.saas.service.RepairCostAdjustExplainService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.xbongbong.saas.script.help.InitExplainsHelper.commonFiledInit;

/**
 * @author WuHB
 * @date 2021/11/18 20:31
 */
@Service("repairCostAdjustExplainService")
public class RepairCostAdjustExplainServiceImpl implements RepairCostAdjustExplainService {

    private static final Logger LOG = LoggerFactory.getLogger(RepairCostAdjustExplainServiceImpl.class);

    @Resource
    private PaasFormExplainModel paasFormExplainModel;

    @Override
    public String repairInitCostAdjustExplain(ProductDTO productDTO) throws XbbException {
        long start = DateTimeUtil.getInt();
        // 需要更新的字段解释集合
        List<FieldAttrEntity> costAdjustFieldAttrEntityList = new ArrayList<>(2);
        List<TempCostAdjustEnum> fieldAttrEntityList = TempCostAdjustEnum.getAllEnum();
        for (TempCostAdjustEnum tempContractOutstockEnum : fieldAttrEntityList) {
            CostAdjustEnum anEnum = tempContractOutstockEnum.getAnEnum();
            // 包装业务枚举类
            EnumBase<CostAdjustEnum> enumBase = new EnumBase<>(anEnum);
            Class<?> clazz = enumBase.t.getClass();
            // 获取业务枚举类中的属性，以集合的形式返回，同一个枚举的属性值只获取一次
            List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(clazz);
            // 需要更新的字段解释
            FieldAttrEntity fieldAttrEntity = InitExplainsHelper.setField(enumBase, enumAttrs);
            if (fieldAttrEntity == null) {
                continue;
            }
            String saasAttr = fieldAttrEntity.getSaasAttr();
            String attr = saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1);
            String methodName = "init" + attr;
            try {
                commonFiledInit(fieldAttrEntity);
                Method method = TempContractOutstockEnum.class.getMethod(methodName, FieldAttrEntity.class);
                method.invoke(tempContractOutstockEnum, fieldAttrEntity);
            } catch (NoSuchMethodException e) {
                LOG.warn("未找到对应字段的初始化方法");
            } catch (Exception e) {
                LOG.error(e.getMessage());
            }
            fieldAttrEntity.setDefaultName(tempContractOutstockEnum.getAnEnum().getAttrName());
            costAdjustFieldAttrEntityList.add(fieldAttrEntity);
        }

        List<String> corpidList = Arrays.asList("1", "0");
        // 更新表单解释
        Map<String, Object> queryFormExplainMap = new HashMap<>();
        queryFormExplainMap.put("businessType", XbbRefTypeEnum.COST_ADJUST.getCode());
        queryFormExplainMap.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
        queryFormExplainMap.put("del", 0);
        queryFormExplainMap.put("saasMark", 1);
        int count = 0;
        int notRepaire = 0;
        List<String> errorCorpidList = new ArrayList<>();
        for (String corpid : corpidList) {
            queryFormExplainMap.put("corpid", corpid);
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(queryFormExplainMap);
            List<PaasFormExplainEntity> newPaasFormExplainList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (PaasFormExplainEntity paasFormExplainEntity : paasFormExplainEntityList) {
                // 解释为空的走默认解释
                if (Objects.isNull(paasFormExplainEntity) || Objects.equals(paasFormExplainEntity.getExplains(),"[]")) {
                    ++count;
                    ++notRepaire;
                    LOG.warn("corpid: " + corpid + "表单formId:---"+paasFormExplainEntity.getId()+"---走默认解释无需更新!");
                    continue;
                }
                for (FieldAttrEntity fieldAttrEntity : costAdjustFieldAttrEntityList) {
                    if (Objects.equals(CostAdjustEnum.PRODUCT.getAttr(), fieldAttrEntity.getAttr())) {
                        SubFormPoJo subFormPoJo = new SubFormPoJo();
                        subFormPoJo.setItems(getProductFromExplain());
                        fieldAttrEntity.setSubForm(subFormPoJo);
                    }
                }
                paasFormExplainEntity.setExplains(JSONObject.toJSONString(costAdjustFieldAttrEntityList));
                newPaasFormExplainList.add(paasFormExplainEntity);
            }
            try {
                if ( CollectionsUtil.isNotEmpty(newPaasFormExplainList) ) {
                    paasFormExplainModel.updateBatch(newPaasFormExplainList, corpid);
                }
                ++count;
                LOG.warn("corpid: " + corpid + "已更新完毕！");
                LOG.warn("当前已更新" + count + "家公司，当总前进度" + count + "/" + +corpidList.size());
            } catch (Exception e) {
                LOG.error("表单解释更新失败", e);
                LOG.warn(corpid + "更新失败，已更新进度" + count + "/" + corpidList.size());
                errorCorpidList.add(corpid);
            }
        }
        JSONObject object = new JSONObject();
        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功,本次共更新" + corpidList.size() + "家公司，其中:" + count + " 家已更新，" + "走默认解释公司共：" + notRepaire + "家");
        LOG.error("更新失败公司ID集合" + errorCorpidList.toString());
        object.put("success", "成功");
        return object.toJSONString();
    }

    /**
     * 修复成本调整单关联产品ID解释
     *
     * @param productDTO productDTO
     * @return 消息
     */
    @Override
    public String repairCostAdjustProductExplain(ProductDTO productDTO) throws XbbException {
        List<String> corpidList = productDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            return "CorpidList为空";
        }
        long start = DateTimeUtil.getInt();
        // 更新表单解释
        Map<String, Object> queryFormExplainMap = new HashMap<>();
        queryFormExplainMap.put("businessType", XbbRefTypeEnum.COST_ADJUST.getCode());
        queryFormExplainMap.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
        queryFormExplainMap.put("del", 0);
        queryFormExplainMap.put("saasMark", 1);

        Map<String, Object> productParams = new HashMap<>();
        productParams.put("businessType", XbbRefTypeEnum.PRODUCT.getCode());
        productParams.put("del", 0);

        int count = 0;
        int notRepaire = 0;
        List<String> errorCorpidList = new ArrayList<>();
        for (String corpid : corpidList) {
            productParams.put("corpid", corpid);
            List<PaasFormExplainEntity> productExplainEntityList = paasFormExplainModel.findEntitys(productParams);
            if (CollectionsUtil.isEmpty(productExplainEntityList)) {
                ++count;
                ++notRepaire;
                LOG.warn("corpid: " + corpid + "未找到产品解释");
                continue;
            }
            PaasFormExplainEntity formExplainEntity = productExplainEntityList.get(0);
            queryFormExplainMap.put("corpid", corpid);
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(queryFormExplainMap);
            for (PaasFormExplainEntity paasFormExplainEntity : paasFormExplainEntityList) {
                // 解释为空的走默认解释
                if (Objects.isNull(paasFormExplainEntity) || Objects.equals(paasFormExplainEntity.getExplains(),"[]")) {
                    ++count;
                    ++notRepaire;
                    LOG.warn("corpid: " + corpid + "表单formId:---"+paasFormExplainEntity.getId()+"---走默认解释无需更新!");
                    continue;
                }
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains());
                if (!explainMap.containsKey(CostAdjustEnum.PRODUCT.getAttr())) {
                    continue;
                }
                FieldAttrEntity fieldAttrEntity1 = explainMap.get(CostAdjustEnum.PRODUCT.getAttr());
                SubFormPoJo subForm = fieldAttrEntity1.getSubForm();
                List<? extends FieldAttrEntity> items = subForm.getItems();
                if (CollectionsUtil.isEmpty(items)) {
                    continue;
                }
                for (FieldAttrEntity item : items) {
                    if (Objects.equals(CostAdjustProductEnum.PRODUCT.getAttr(), item.getAttr())) {
                        LinkInfoPojo linkInfo = item.getLinkInfo();
                        linkInfo.setLinkFormId(formExplainEntity.getFormId());
                        linkInfo.setLinkAppId(formExplainEntity.getAppId());
                        linkInfo.setLinkMenuId(formExplainEntity.getMenuId());
                    }
                }
                paasFormExplainEntity.setExplains(JSONObject.toJSONString(explainMap));
            }
            try {
                if ( CollectionsUtil.isNotEmpty(paasFormExplainEntityList) ) {
                    paasFormExplainModel.updateBatch(paasFormExplainEntityList, corpid);
                }
                ++count;
                LOG.warn("corpid: " + corpid + "已更新完毕！");
                LOG.warn("当前已更新" + count + "家公司，当总前进度" + count + "/" + +corpidList.size());
            } catch (Exception e) {
                LOG.error("表单解释更新失败", e);
                LOG.warn(corpid + "更新失败，已更新进度" + count + "/" + corpidList.size());
                errorCorpidList.add(corpid);
            }
        }
        JSONObject object = new JSONObject();
        LOG.warn("consume:" + (DateTimeUtil.getInt() - start));
        LOG.warn("操作成功,本次共更新" + corpidList.size() + "家公司，其中:" + count + " 家已更新，" + "走默认解释公司共：" + notRepaire + "家");
        LOG.error("更新失败公司ID集合" + errorCorpidList.toString());
        object.put("success", "成功");
        return object.toJSONString();

    }

    private List<FieldAttrEntity> getProductFromExplain() {
        // 需要更新的字段解释集合
        List<FieldAttrEntity> productFieldAttrEntityList = new ArrayList<>();
        List<TempCostAdjustProductEnum> fieldAttrEntityList = TempCostAdjustProductEnum.getAllEnum();
        for (TempCostAdjustProductEnum tempContractOutstockEnum : fieldAttrEntityList) {
            CostAdjustProductEnum anEnum = tempContractOutstockEnum.getAnEnum();
            // 包装业务枚举类
            EnumBase<CostAdjustProductEnum> enumBase = new EnumBase<>(anEnum);
            Class<?> clazz = enumBase.t.getClass();
            // 获取业务枚举类中的属性，以集合的形式返回，同一个枚举的属性值只获取一次
            List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(clazz);
            // 需要更新的字段解释
            FieldAttrEntity fieldAttrEntity = InitExplainsHelper.setField(enumBase, enumAttrs);
            if (fieldAttrEntity == null) {
                continue;
            }
            String saasAttr = fieldAttrEntity.getSaasAttr();
            String attr = saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1);
            String methodName = "init" + attr;
            try {
                commonFiledInit(fieldAttrEntity);
                Method method = TempContractOutstockEnum.class.getMethod(methodName, FieldAttrEntity.class);
                method.invoke(tempContractOutstockEnum, fieldAttrEntity);
            } catch (NoSuchMethodException e) {
                LOG.warn("未找到对应字段的初始化方法");
            } catch (Exception e) {
                LOG.error(e.getMessage());
            }
            fieldAttrEntity.setDefaultName(tempContractOutstockEnum.getAnEnum().getAttrName());
            productFieldAttrEntityList.add(fieldAttrEntity);
        }
        return productFieldAttrEntityList;
    }
}
